<html>
	<head>
        <meta charset="UTF-8">
        <!-- <script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v6.1.1/build/ol.js"></script> -->
        <script src="http://106.15.200.245/cdn/ol.js"></script>
        <script src="https://www.intermezzo-coop.eu/mapping/geostats/lib/geostats.js"></script>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
        <script src="https://cdn.bootcss.com/jquery-cookie/1.4.1/jquery.cookie.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/chroma-js/1.2.1/chroma.min.js"></script>
        <!-- <link rel="stylesheet" href="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v6.1.1/css/ol.css"> -->
        <link href="http://106.15.200.245/cdn/ol.css" rel="stylesheet">
    </head>
    <select id="methodselector" class="form-control">
        <option value="method_EI" >相等的时间间隔</option>
        <option value="method_Q" selected>分位数</option>
        <option value="method_SD" >标准偏差</option>
        <option value="method_AP" >等差数列</option>
        <option value="method_GP" >几何级数</option>
        <option value="method_CJ">类詹金斯</option>                  
      </select>
      shp内属性名
      <input type="number" id="classcount" min="1" value="5" max="10">
      <select id="mySelect">
        <option>请选择</option>
        </select>
      <input type="button" id="drawitbtn" onclick="drawIt()" value='开始渲染'/>

    <div id="map"></div>
    <div id='legend'></div>
	<script>
        var globalOptions;
        
        var layerName = $.cookie("layername");
        var workName = $.cookie("workname");
        var hasLayer = $.cookie("no");

        var myname = $.cookie("name");
        var myvalue = $.cookie("value");
        var project = $.cookie("project");

        console.log(hasLayer);
        console.log(workName);
        console.log(layerName);

        // var json = JSON.parse(localStorage.getItem('device'));
        console.log("json");
        // console.log(json);

            //some global vars here
            var classSeries;
            var classColors;
            //color start from
            var colorFrom ='FFFFFF';
            //color end to
            var colorTo = '1A8B16';
            var defaultStyle = new ol.style.Style({
            fill: new ol.style.Fill({
                color: 'rgba(255, 255, 255, 0.3)'
            }),
            stroke: new ol.style.Stroke({
                color: 'rgba(0, 255, 0, 1)',
                width: 1
            }),
            text: new ol.style.Text({
                font: '12px Calibri,sans-serif',
                fill: new ol.style.Fill({
                color: '#000'
                }),
                stroke: new ol.style.Stroke({
                color: '#fff',
                width: 3
                })
            })
            });
            var map = new ol.Map({
                    layers: [
                        new ol.layer.Tile({
                            source: new ol.source.OSM()
                        }),
                    ],
                    target: 'map',
                    view: new ol.View({
                        center: ol.proj.fromLonLat([119.545322, 26.201018]),
                        zoom: 12
                                                // maxZoom: 19
                    })
                });      
            async function ajax(){
                var json = "1";
                var data = await new Promise((resolve,reject)=>{
                    $.ajax({
                        url: "http://106.15.200.245:50000/auth_api/device_list",
                        headers:{
                            "token":sessionStorage['token']
                        },
                        data: {
                            page:1,
                            limit:1000,
                            isMap:false,
                            project: project
                        },
                        type: "get",
                        dataType: "json",
                        success:(res)=>{
                            json = res.data;
                            console.log(res.data);                            
                            resolve('ok');
                            // data = jQuery.parseJSON(data);  //dataType指明了返回数据为json类型，故不需要再反序列化
                        }
                    })                   
                })
                console.log(json);
                    //此示例创建10000个要素
                    var count = json.length;
                    var features = new Array(count);
                    // var e = 4500000;
                    console.log(ol.proj.fromLonLat([119.30, 26.08]));
                    for(var i = 0; i < count; i++){
                        var coordinates = [];
                        coordinates.push(json[i].longitude);
                        coordinates.push(json[i].latitude);
                        console.log("coord");
                        console.log(coordinates);
                        features[i] = new ol.Feature({
                            geometry: new ol.geom.Point(ol.proj.fromLonLat(coordinates)),
                            name: json[i].customSerial
                        });
                        features[i].setId(json[i].customSerial);
                    }
                    console.log(features);
                    //矢量要素数据源
                    var source2 = new ol.source.Vector({
                        features: features
                    });
                    //聚合标注数据源
                    var clusterSource = new ol.source.Cluster({
                        distance: 40,               //聚合的距离参数，即当标注间距离小于此值时进行聚合，单位是像素
                        source: source2              //聚合的数据源，即矢量要素数据源对象
                    });
                    //加载聚合标注的矢量图层
                    var styleCache = {};                  //用于保存特定数量的聚合群的要素样式
                    
                    //不用聚合会卡死，用聚合又无法确定设备ID
                    var clusters = new ol.layer.Vector({
                        source: clusterSource,
                        style: function (feature, resolution){
                            var size = feature.get('features').length;          //获取该要素所在聚合群的要素数量
                            // var style = styleCache[size];
                            var style = [];
                            // console.log(feature.get('features'));
                            for(var i = 0 ; i < feature.get('features').length; i++){
                                // console.log(feature.get('features')[i]);
                                style.push(
                                    new ol.style.Style({
                                        image: new ol.style.Circle({
                                            radius: 21,
                                            stroke: new ol.style.Stroke({
                                                color: '#fff'
                                            }),
                                            fill: new ol.style.Fill({
                                                color: '#3399CC'
                                            })
                                        }),
                                        text: new ol.style.Text({
                                            text: feature.get('features')[i].id_,
                                            fill: new ol.style.Fill({
                                                color: '#fff'
                                            }),
                                            font:"5px"
                                        })
                                    })
                                )
                            }
                            return style;
                        }
                    });
                    map.addLayer(clusters);                 
            }
            ajax();
                    //our methods here
                    var layerNames = [];
                    layerNames.push(layerName);
            var url1="http://106.15.200.245:8080/geoserver/wfs?service=wfs&version=1.0.0&request=getfeature&typename=A350104754:lj_20170307&outputformat=application/json";
            // 这里也要用变量来替换的
            var featureRequest = new ol.format.WFS().writeGetFeature({
                                srsName: 'EPSG:3857',
                                featurePrefix: workName,
                                featureNS: workName,
                                featureTypes: layerNames,
                                propertyNames:['XBH','LBH','DBH','the_geom'],
                                outputFormat: 'application/json',
                                // filter: ol.format.filter.equalTo(myname,myvalue)
                                filter: ol.format.filter.and(
                                //     ol.format.filter.bbox('the_geom',extent, 'EPSG:3857'),
                                    ol.format.filter.like('XBH','*'),
                                    ol.format.filter.like('LBH','*'),
                                    ol.format.filter.like('DBH','*')
                                )
                            });
            let filter=new XMLSerializer().serializeToString(featureRequest);
                                        //${GEOSERVER_URL}/wfs?service=wfs&version=1.0.0&request=getfeature&typename=${ACC_ROAD_WFS_NAME}&PROPERTYNAME=name,fid,geom&CQL_FILTER=fid in (${crossIds.join(',')})&outputformat=application/json`

            var source = new ol.source.Vector({
                    // style: defaultStyle,
                    format: new ol.format.GeoJSON(),
                    // url: url1,
                    loader: function(extent, resolution, projection) {
                        console.log(extent.join(','));
                        console.log(extent);

                            var proj = projection.getCode();
                            // var url = url1;
                            // url = url + '&srsname=EPSG:3857&bbox=' + extent.join(',') + ',EPSG:3857';
                            var url = "http://106.15.200.245:8080/geoserver/wfs?service=wfs&version=1.0.0&request=getfeature&typename=" + workName + ":" + layerName +  "&outputformat=application/json";
                            var xhr = new XMLHttpRequest();
                            xhr.open('POST', url);
                            xhr.setRequestHeader("Content-type", "text/xml");
                            var onError = function() {
                                source.removeLoadedExtent(extent);
                            }
                            xhr.onerror = onError;
                            xhr.onload = ()=>{
                                if (xhr.status == 200 && xhr.readyState == 4) {
                                    // setTimeout(()=>{                                
                                    var unitObj=document.getElementById("mySelect");
                                    var feas = [];
                                    feas = source.getFormat().readFeatures(xhr.responseText);
                                    var json = feas[0].values_;
                                    for(key in json){
                                        if(key == 'geometry')
                                            continue;
                                        console.log(key);
                                        unitObj.options.add(new Option(key,key));
                                    }
                                    source.addFeatures(feas);
                                    // },5000)
                                } else {
                                    onError();
                                }
                            }
                            xhr.send(filter);
                         },
                        //  strategy: ol.loadingstrategy.bbox
                });

                                    // var clusterSource2 = new ol.source.Cluster({
                                    //             distance: 40,              //聚合的距离参数，即当标注间距离小于此值时进行聚合，单位是像素
                                    //              source:source,
                                    //              geometryFunction: function(coordinates) {
                                    //                 //  console.log(coordinates);
                                    //                 //  console.log(coordinates.getGeometry());
                                    //                 //  console.log(geometry);
                                    //                 // console.log(poly);
                                    //                 // debugger;
                                    //                  return coordinates;
                                    //              }
                                    //         });
                                    var vectorLayer = new ol.layer.Vector({
                                            source: source,
                                            style: new ol.style.Style({
                                                stroke: new ol.style.Stroke({
                                                    color: 'rgba(0, 0, 255, 1.0)',
                                                    width: 2
                                                })
                                            }),                                           
                                            format: new ol.format.GeoJSON({
                                                        defaultDataProjection:'EPSG:4326',
                                                        featureProjection:'EPSG:3857'
                                                        })                
                                            })

                                        if(hasLayer=="no"){

                                        }else{
                                            map.addLayer(vectorLayer);
                                        }

            /**
             * do the themmatic
             */
            function drawIt(){
                var options=$("#mySelect option:selected");
                console.log(options.val());

                globalOptions = options;


                                
            var countryPopVals = new Array();
            vectorLayer.getSource().getFeatures().forEach(function(feat) {
                
            // countryPopVals.push(feat.get("XBH"))
            countryPopVals.push(feat.get(options.val()))
            });
            console.info("countryPopVals",countryPopVals);
            getAndSetClassesFromData(countryPopVals, getClassNum(), getMethod());
            vectorLayer.setStyle(setStyle);
            }


            /**
             * @data {Array} the array of numbers (these are the pop data for all countries)
             * @numclasses {Integer} get the number of classes
             * @method {String}  get the classification method
             * 
             *
             * set geostats object
             * set the series
             * set the colors ramp        
             * 
             */
            function getAndSetClassesFromData(data, numclasses, method) {
            var serie = new geostats(data);
            var legenLabel = ""; 
            if (method === "method_EI") {
                serie.getClassEqInterval(numclasses);
                methodLabel = "Equal Interval";
            } else if (method === "method_Q") {
                serie.getClassQuantile(numclasses);
                methodLabel = "Quantile";
            } else if (method === "method_SD") {
                serie.getClassStdDeviation(numclasses);
                methodLabel = "Standard Deviation ";
            } else if (method === "method_AP") {
                serie.getClassArithmeticProgression(numclasses);
                methodLabel = "Arithmetic Progression";
            } else if (method === "method_GP") {
                serie.getClassGeometricProgression(numclasses);
                methodLabel = "Geometric Progression ";
            } else if (method === "method_CJ") {
                serie.getClassJenks(numclasses);
                methodLabel = "Class Jenks";
            } else {
            alert("error: no such method.")
            }
            var colors_x = chroma.scale([colorFrom, colorTo]).colors(numclasses)

            serie.setColors(colors_x);
            document.getElementById('legend').innerHTML = serie.getHtmlLegend(null, "World Population</br> Method:"+methodLabel, 1);
            classSeries = serie;
            classColors = colors_x; 
            }

            /**
             * function to verify the style for the feature
             */
            function setStyle(feat,res) {
            var currVal = parseFloat(feat.get(globalOptions.val())); 
            var bounds = classSeries.bounds;
            var numRanges = new Array();
            for (var i = 0; i < bounds.length-1; i++) { 
            numRanges.push({
                min: parseFloat(bounds[i]),
                max: parseFloat(bounds[i+1])
                });  
            }  
            var classIndex = verifyClassFromVal(numRanges, currVal);
            var polyStyleConfig = {
                stroke: new ol.style.Stroke({
                color: 'rgba(255, 0, 0,0.3)',
                width: 1
                })
            };

            var textStyleConfig = {};
            // var label = res < 5000 ? feat.get(globalOptions.val()) : '';
            var label1 = res < 5000 ? feat.get('LBH') : '';
            var label2 = res < 5000 ? feat.get('DBH') : '';
            var label3 = res < 5000 ? feat.get('XBH') : '';
            if (classIndex !== -1) {
                polyStyleConfig = {
                stroke: new ol.style.Stroke({
                    color: 'rgba(0, 0, 255, 1.0)',
                    width: 1
                }),
                fill: new ol.style.Fill({
                    color: hexToRgbA(classColors[classIndex],0.7)
                })
                };
                textStyleConfig = {
                text: new ol.style.Text({
                    text: label1 + "_" + label2 + "_" +label3,
                    font: '12px Calibri,sans-serif',
                    fill: new ol.style.Fill({
                    color: "#000000"
                    }),
                    stroke: new ol.style.Stroke({
                    color: "#FFFFFF",
                    width: 2
                    })
                }),
                geometry: function(feature) {
                    var retPoint;
                    if (feature.getGeometry().getType() === 'MultiPolygon') {
                    retPoint = getMaxPoly(feature.getGeometry().getPolygons()).getInteriorPoint();
                    } else if (feature.getGeometry().getType() === 'Polygon') {
                    retPoint = feature.getGeometry().getInteriorPoint();
                    }
                    
                    return retPoint;
                }
                }
            };

            var textStyle = new ol.style.Style(textStyleConfig);
            var style = new ol.style.Style(polyStyleConfig);
            return [style,textStyle];
            }

            //*************helper functions this point forward***************//
            
            function verifyClassFromVal(rangevals, val) {
            var retIndex = -1;
            for (var i = 0; i < rangevals.length; i++) {
                if (val >= rangevals[i].min && val <= rangevals[i].max) {
                retIndex = i;
                }
            }
            return retIndex;
            }

            /**
            *   get the user selected method
            */
            function getMethod(){
            var elem = document.getElementById("methodselector");
            var val = elem.options[elem.selectedIndex].value;
            return val;
            }

            /**
            *   get the user selected number of classes
            */
            function getClassNum(){
            var elem = document.getElementById("classcount");
            return parseInt(elem.value);
            }


            /**
            * convert hex to rgba 
            *
            */
            function hexToRgbA(hex,opacity) {
            var c;
            if (/^#([A-Fa-f0-9]{3}){1,2}$/.test(hex)) {
                c = hex.substring(1).split('');
                if (c.length == 3) {
                c = [c[0], c[0], c[1], c[1], c[2], c[2]];
                }
                c = '0x' + c.join('');
                return 'rgba(' + [(c >> 16) & 255, (c >> 8) & 255, c & 255].join(',') + ','+opacity+')';
            }
            throw new Error('Bad Hex');
            }
            /**
            *    get the maximum polygon out of the supllied  array of polygon
            *    used for labeling the bigger one
            */
            function getMaxPoly(polys) {
            var polyObj = [];
            //now need to find which one is the greater and so label only this
            for (var b = 0; b < polys.length; b++) {
                polyObj.push({
                poly: polys[b],
                area: polys[b].getArea()
                });
            }
            polyObj.sort(function(a, b) {
                return a.area - b.area
            });

            return polyObj[polyObj.length - 1].poly;
            }

	</script>
</html>